import { Drawer, Form, Spin, Input, Button, Switch, Select } from "antd";
import { DrawerProps } from "antd/es/drawer";
import { useForm } from "antd/lib/form/Form";
import { UploadFile, UploadChangeParam } from "antd/lib/upload/interface";
import { useState, useEffect, useRef } from "react";
import styled from "@emotion/styled";
import MarkdownIt from "markdown-it";
import MdEditor from "react-markdown-editor-lite";
import "react-markdown-editor-lite/lib/index.css";

import { ErrorBox } from "components/lib";
import { UploadImage } from "components/upload-image";
import { useAddArticle, useArticleParam, useModifyArticle } from "./util";
import { useHttp } from "utils/http";
import { useLabels } from "pages/label/util";

const mdParser = new MarkdownIt(/* Markdown-it options */);

export const CreateArticle = (
  props: Pick<DrawerProps, "visible"> & { onClose: () => void }
) => {
  const { mutateAsync: addArticle, isLoading: isAddLoading } = useAddArticle();

  const [form] = useForm();
  const [img, setImg] = useState<UploadFile[]>([]);
  const [messageError, setMessageError] = useState<Error | null>(null);
  const [content, setContent] = useState("");
  const { article, isLoading, id } = useArticleParam();
  const { mutateAsync: modifyArticle, isLoading: isModifyLoading } =
    useModifyArticle();

  const { data: labels } = useLabels();

  useEffect(() => {
    setMessageError(null);
    if (article) {
      let label_ids: number[] = [];
      article.labels.forEach((item) => {
        label_ids.push(item.id || 0);
      });

      const formValue = {
        ...article,
        status: article.status === 1 ? true : false,
        label_ids,
      };
      console.log(article.content);
      setContent(article.content);

      setImg([
        {
          uid: "1",
          url: article.thumb,
          name: article.thumb,
          status: "done",
        },
      ]);
      form.setFieldsValue(formValue);
    } else {
      form.resetFields();
      form.setFieldsValue({ status: true });
    }
  }, [form, props.visible, article]);

  const onFinish = async (values: any) => {
    const status = form.getFieldsValue().status ? 1 : 2;
    let imgImport = "";
    if (img.length > 0) {
      imgImport = img[0].response ? img[0].response.key : img[0].url;
    }
    if (article) {
      await modifyArticle({
        ...form.getFieldsValue(),
        id,
        thumb: imgImport,
        content,
        status,
      })
        .then(() => {
          props.onClose();
        })
        .catch((error) => {
          error = setMessageError(new Error(error.message));
        });
    } else {
      await addArticle({
        ...form.getFieldsValue(),
        thumb: imgImport,
        status,
        content,
      })
        .then(() => {
          props.onClose();
        })
        .catch((error) => setMessageError(error));
    }
  };

  const changeImage = (info: UploadChangeParam<UploadFile<any>>) => {
    if (info.file.status === "removed") {
      setImg([]);
    }
    if (info.file.status === "done") {
      setImg(info.fileList);
    }
  };

  const client = useHttp();
  let qiniu = useRef({ token: "", qiniu_url_prefix: "" });
  useEffect(() => {
    client("label/qiniu").then((res) => {
      qiniu.current = res;
    });
  }, [client]);

  const handleImageUpload = async (file: File) => {
    const fd = new FormData();
    const token = qiniu.current?.token;
    const prefix = qiniu.current?.qiniu_url_prefix;
    fd.append("token", token);
    fd.append("file", file);
    return window
      .fetch(`http://upload.qiniu.com`, {
        method: "POST",
        body: fd,
      })
      .then(async (res) => {
        const data = await res.json();
        return prefix + data.key;
      });
  };

  const handleEditorChange = ({
    html,
    text,
  }: {
    html: string;
    text: string;
  }) => {
    setContent(text);
  };

  const onImgClose = () => {
    setImg([]);
    setContent("");
    props.onClose();
  };

  return (
    <Drawer
      visible={props.visible}
      onClose={onImgClose}
      forceRender={true}
      destroyOnClose={true}
      width={"100%"}
    >
      <Container>
        {isAddLoading || isLoading ? (
          <Spin size={"large"} />
        ) : (
          <>
            <h2>{article ? "编辑" + article.title : "创建"}</h2>
            <ErrorBox error={messageError} />
            <Form
              form={form}
              layout={"horizontal"}
              style={{ width: "80%" }}
              onFinish={onFinish}
            >
              <Form.Item
                label={"标题"}
                name={"title"}
                rules={[{ required: true, message: "请输入标题" }]}
              >
                <Input placeholder="请输入标题" />
              </Form.Item>

              <Form.Item
                label={"标签"}
                name={"label_ids"}
                rules={[{ required: true, message: "请选择标签" }]}
              >
                <Select mode="multiple" allowClear>
                  {labels?.map((label) => (
                    <Select.Option key={label.id} value={label.id || 0}>
                      {label.title}
                    </Select.Option>
                  ))}
                </Select>
              </Form.Item>

              <Form.Item label={"状态"} name={"status"} valuePropName="checked">
                <Switch checkedChildren="启用" unCheckedChildren="禁用" />
              </Form.Item>

              <Form.Item label={"图片"}>
                <UploadImage
                  modalTitle={"裁切图片"}
                  aspect={1.25}
                  nums={1}
                  onChange={changeImage}
                  value={img}
                />
              </Form.Item>

              <Form.Item label={"内容"}>
                <MdEditor
                  style={{ height: "500px" }}
                  value={content}
                  renderHTML={(text) => mdParser.render(text)}
                  onChange={handleEditorChange}
                  onImageUpload={handleImageUpload}
                />
              </Form.Item>

              <Form.Item style={{ textAlign: "right" }}>
                <Button
                  loading={isAddLoading || isModifyLoading}
                  type={"primary"}
                  htmlType={"submit"}
                >
                  提交
                </Button>
              </Form.Item>
            </Form>
          </>
        )}
      </Container>
    </Drawer>
  );
};

const Container = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
`;
